<?php
/**
 * 基础Model类
 * Created by PhpStorm.
 * User: phperstar
 * Date: 2022/4/6
 * Time: 11:37
 */

declare (strict_types=1);

namespace app\api\service\boss;

use app\common\service\BaseService;

class MBaseService extends BaseService
{
    public function __construct()
    {

    }


    // 根据当前时间计算环比时间
    public static function getChainRelativeTime($selectParams)
    {
        switch ($selectParams['dateType']) {
            case 0: // 今日
                $unixTime = self::gettimestamp('yesterday');
                break;
            case 1: // 昨日
                $unixTime = self::gettimestamp('yesterday');
                $interval = $unixTime['end'] - $unixTime['start'] + 1;
                $unixTime['start'] = $unixTime['start'] - $interval;
                $unixTime['end'] = $unixTime['end'] - $interval;
                break;
            case 2: // 近七天
                $unixTime = self::gettimestamp('lastSevenDay');
                $interval = $unixTime['end'] - $unixTime['start'] + 1;
                $unixTime['start'] = $unixTime['start'] - $interval;
                $unixTime['end'] = $unixTime['end'] - $interval;
                break;
            case 3: // 本周
                $unixTime = self::gettimestamp('preweek');
                break;
            case 4: // 上周
                $unixTime = self::gettimestamp('preweek');
                $interval = $unixTime['end'] - $unixTime['start'] + 1;
                $unixTime['start'] = $unixTime['start'] - $interval;
                $unixTime['end'] = $unixTime['end'] - $interval;
                break;
            case 5: // 本月
                $unixTime = self::gettimestamp('permonth');
                break;
            case 6: // 上月
                $unixTime = self::gettimestamp('perpermonth');
                break;
            case 7: // 本季度
                $unixTime = self::gettimestamp('lastQuarter');
                break;
            case 8: // 上季度
                $unixTime = self::gettimestamp('lastpreQuarter');
                break;
            case 9: // 本年
                $unixTime = self::gettimestamp('preyear');
                break;
            case 10: // 去年
                $unixTime = self::gettimestamp('prepreyear');
                break;
            case 11: // 自定义
                $unixTime['start'] = $selectParams['startTime'];
                $unixTime['end'] = $selectParams['endTime'];

                $interval = $unixTime['end'] - $unixTime['start'] + 1;
                $unixTime['start'] = $unixTime['start'] - $interval;
                $unixTime['end'] = $unixTime['end'] - $interval;
                break;
        }
        $selectParams['chainRelativeStartTime'] = $unixTime['start'];
        $selectParams['chainRelativeEndTime'] = $unixTime['end'];

        return $selectParams;
    }

    // 根据筛选计算时间分组方式
    public static function sqlUnixFormat($selectParams)
    {
        switch ($selectParams['dateType']) {
            case 0: // 今日
            case 1: // 昨日
                $format = '%H';
                break;
            case 2: // 近七天
            case 3: // 本周
            case 4: // 上周
            case 5: // 本月
            case 6: // 上月
                $format = '%Y-%m-%d';
                break;
            case 7: // 本季度
            case 8: // 上季度
            case 9: // 本年
            case 10: // 去年
                $format = '%Y-%m';
                break;
            case 11: // 自定义
                $format = self::getUnixFormatByTime($selectParams['startTime'], $selectParams['endTime']);
                break;
        }

        return $format;
    }

    // 自定义时间根据间隔天数计算时间归组维度
    public static function getUnixFormatByTime($startTime, $endTime)
    {
        $days = ($endTime - $startTime) / (24 * 60 * 60);
        switch ($days) {
            case $days >= 365:
                $format = '%Y';
                break;
            case $days >= 90:
            case $days >= 30:
                $format = '%Y-%m';
                break;
            case $days <= 1:
                $format = '%H';
                break;
            default:
                $format = '%Y-%m-%d';
                break;
        }

        return $format;
    }

    // 趋势数据组装
    public static function formatCurveData($selectParams, $result)
    {
        switch ($selectParams['dateType']) {
            case 0: // 今日
            case 1: // 昨日
                $curveData = self::createCurveDataByHours($result);
                break;
            case 2: // 近七天
                $curveData = self::createCurveDataByDay($result, 2);
                break;
            case 3: // 本周
                $curveData = self::createCurveDataByDay($result, 3);
                break;
            case 4: // 上周
                $curveData = self::createCurveDataByDay($result, 4);
                break;
            case 5: // 本月
                $curveData = self::createCurveDataByDay($result, 5);
                break;
            case 6: // 上月
                $curveData = self::createCurveDataByDay($result, 6);
                break;
            case 7: // 本季度
                $curveData = self::createCurveDataByDay($result, 7);
                break;
            case 8: // 上季度
                $curveData = self::createCurveDataByDay($result, 8);
                break;
            case 9: // 本年
                $curveData = self::createCurveDataByDay($result, 9);
                break;
            case 10: // 上年
                $curveData = self::createCurveDataByDay($result, 10);
                break;
            case 11: // 自定义
                $curveData = self::specialCondition($selectParams, $result);
                break;
        }

        return $curveData;
    }

    // 计算自定义日期的数据组装方式
    static function specialCondition($selectParams, $result)
    {
        $saleMoney = [];
        $days = ($selectParams['endTime'] - $selectParams['startTime']) / (24 * 60 * 60);
        if (!empty($result)) {
            foreach ($result as $key => $value) {
                $timeBindSaleMoney[$value['addtime']] = $value['saleMoney'];

                $saleMoney['date'][] = $value['addtime'];
                $saleMoney['money'][] = sprintf("%.2f", $value['saleMoney']);
            }
        }

        return $saleMoney;
    }

    // 按照日生成曲线数据 - 天维度
    public static function createCurveDataByDay($result, $type, $interval = 0)
    {
        $timeBindSaleMoney = [];
        if (!empty($result)) {
            foreach ($result as $key => $value) {
                $timeBindSaleMoney[$value['addtime']] = $value['saleMoney'];
            }
        }

        switch ($type) {
            case 2:
                $saleMoney = self::lastSeven($timeBindSaleMoney);
                break;
            case 3:
                $saleMoney = self::week($timeBindSaleMoney);
                break;
            case 4:
                $saleMoney = self::lastWeek($timeBindSaleMoney);
                break;
            case 5:
                $saleMoney = self::month($timeBindSaleMoney);
                break;
            case 6:
                $saleMoney = self::lastMonth($timeBindSaleMoney);
                break;
            case 7:
                $saleMoney = self::quarter($timeBindSaleMoney);
                break;
            case 8:
                $saleMoney = self::lastQuarter($timeBindSaleMoney);
                break;
            case 9:
                $saleMoney = self::year($timeBindSaleMoney);
                break;
            case 10:
                $saleMoney = self::lastYear($timeBindSaleMoney);
                break;
            case 11:
                $saleMoney = self::lastYear($timeBindSaleMoney);
                break;
        }

        return $saleMoney;
    }

    // 按照日生成取消数据 - 24小时制
    public static function createCurveDataByHours($result)
    {
        $timeBindSaleMoney = [];
        if (!empty($result)) {
            foreach ($result as $key => $value) {
                $timeBindSaleMoney[$value['addtime']] = sprintf("%.2f", $value['saleMoney']);
            }
        }

        $saleMoney = [];
        for ($i = 0; $i < 24; $i++) {
            $saleMoney['date'][] = $i;
            $addTime = date(sprintf('%02d', (int)$i));
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? $timeBindSaleMoney[$addTime] : 0;
        }

        return $saleMoney;
    }

    // 最近七天
    static function lastSeven($timeBindSaleMoney)
    {
        $saleMoney = [];
        for ($i = 6; $i >= 0; $i--) {
            $addTime = date('Y-m-d', strtotime('-' . $i . 'days', time()));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }
        return $saleMoney;
    }

    // 本周
    static function week($timeBindSaleMoney)
    {
        $saleMoney = [];
        $week = date('w', time());
        for ($i = 1; $i <= 7; $i++) {
            $a = $i - $week;
            $addTime = date('Y-m-d', strtotime('+' . $a . 'days', time()));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }
        return $saleMoney;
    }

    // 上周
    static function lastWeek($timeBindSaleMoney)
    {
        $saleMoney = [];
        for ($i = 1; $i <= 7; $i++) {
            $addTime = date('Y-m-d', mktime(0, 0, 0, (int)date('m'), (int)date('d') - (int)date('w') + $i - 7, (int)date('Y')));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }
        return $saleMoney;
    }

    // 本月
    static function month($timeBindSaleMoney)
    {
        $saleMoney = [];
        $monthDay = date('t');
        for ($i = 1; $i <= $monthDay; $i++) {
            $addTime = date('Y-m-d', mktime(0, 0, 0, (int)date('m'), $i));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }
        return $saleMoney;
    }

    // 上月
    static function lastMonth($timeBindSaleMoney)
    {
        $saleMoney = [];
        $monthDay = date('t', strtotime(date('Y-m', strtotime('-1 month'))));
        for ($i = 0; $i < $monthDay - 1; $i++) {
            $addTime = date('Y-m-d', strtotime(date('Y-m-01 0:0:0', strtotime('-1 month'))) + $i * 86400);
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }
        return $saleMoney;
    }

    // 本季度
    static function quarter($timeBindSaleMoney)
    {
        $quarter = ceil((date('n')) / 3);
        $startMonth = $quarter * 3 - 2;
        for ($i = 0; $i < 3; $i++) {
            $addTime = date('Y-m', mktime(0, 0, 0, (int)$startMonth + $i, 1, (int)date('Y')));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }

        return $saleMoney;
    }

    // 上季度
    static function lastQuarter($timeBindSaleMoney)
    {
        $quarter = ceil((date('n')) / 3) - 1;
        $startMonth = $quarter * 3 - 3;
        for ($i = 1; $i <= 3; $i++) {
            $addTime = date('Y-m', mktime(0, 0, 0, (int)$startMonth + $i, 1, (int)date('Y')));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }

        return $saleMoney;
    }

    // 本年
    static function year($timeBindSaleMoney)
    {
        for ($i = 1; $i <= 12; $i++) {
            $addTime = date('Y-m', strtotime(date('Y-' . $i)));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }

        return $saleMoney;
    }

    // 去年
    static function lastYear($timeBindSaleMoney)
    {
        for ($i = 1; $i <= 12; $i++) {
            $addTime = date('Y-m', strtotime(date('Y-' . $i, strtotime('-1 year'))));
            $saleMoney['date'][] = $addTime;
            $saleMoney['money'][] = isset($timeBindSaleMoney[$addTime]) ? sprintf("%.2f", $timeBindSaleMoney[$addTime]) : 0;
        }

        return $saleMoney;
    }

    // 自定义年
    static function specialYear($timeBindSaleMoney)
    {

    }

    /**
     * 获取 当天，昨天，本周，本月，本年时间戳
     */

    public static function gettimestamp($name = 'today', $param = '')
    {
        switch ($name) {
            case 'today'://今天
                $timeamp['start'] = strtotime(date('Y-m-d 0:0:0'));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59'));
                break;
            case 'yesterday'://昨天
                $timeamp['start'] = strtotime(date('Y-m-d 0:0:0', strtotime('-1 day')));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59', strtotime('-1 day')));
                break;
            case 'beforyesterday'://前天
                $timeamp['start'] = strtotime(date('Y-m-d 0:0:0', strtotime('-2 day')));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59', strtotime('-2 day')));
                break;
            case 'lastSevenDay': // 近七天
                $timeamp['start'] = strtotime(date('Y-m-d 0:0:0', strtotime('-6 day')));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59'));
                break;
            case 'beforweek'://本周
                $timeamp['start'] = strtotime(date("Y-m-d H:i:s", mktime(0, 0, 0, (int)date("m"), (int)date("d") - (int)date("w") + 1, (int)date("Y"))));
                $timeamp['end'] = strtotime(date("Y-m-d H:i:s", mktime(23, 59, 59, (int)date("m"), (int)date("d") - (int)date("w") + 7, (int)date("Y"))));
                break;
            case 'nowmonth'://本月
                $timeamp['start'] = strtotime(date('Y-m-01 0:0:0'));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59'));
                break;
            case 'permonth'://上月
                $timeamp['start'] = strtotime(date('Y-m-01 0:0:0', strtotime('-1 month')));
                $timeamp['end'] = strtotime(date('Y-m-01')) - 1;
                break;
            case 'perpermonth':// 上上月
                $timeamp['start'] = strtotime(date('Y-m-01 0:0:0', strtotime('-2 month')));
                $timeamp['end'] = strtotime(date('Y-m-01 0:0:0', strtotime('-1 month'))) - 1;
                break;
            case 'preweek'://上周

                $timeamp['start'] = mktime(0, 0, 0, (int)date('m'), (int)date('d') - (int)date('w') + 1 - 7, (int)date('Y'));
                $timeamp['end'] = mktime(23, 59, 59, (int)date('m'), (int)date('d') - (int)date('w') + 7 - 7, (int)date('Y'));
                break;
            case 'nowweek'://本周
                $timeamp['start'] = strtotime(date('Y-m-d', strtotime('-1 week Monday')));
                $timeamp['end'] = strtotime(date('Y-m-d', strtotime('+1 day')));
                break;
            case 'preday'://近三个月
                $timeamp['start'] = strtotime("-0 year -3 month -0 day");
                $timeamp['end'] = strtotime(date('Y-m-d'));
                break;
            case 'nextday'://30
                $timeamp['start'] = strtotime(date('Y-m-d'));
                $timeamp['end'] = strtotime(date('Y-m-d'), strtotime($param . ' day'));
                break;
            case 'preyear'://去年
                $timeamp['start'] = strtotime(date('Y-01-01', strtotime('-1 year')));
                $timeamp['end'] = strtotime(date('Y-12-31 23:59:59', strtotime('-1 year')));
                break;
            case 'nowyear'://今年
                $timeamp['start'] = strtotime(date('Y-01-01'));
                $timeamp['end'] = strtotime(date('Y-m-d 23:59:59'));
                break;
            case 'prepreyear'://前年
                $timeamp['start'] = strtotime(date('Y-01-01', strtotime('-2 year')));
                $timeamp['end'] = strtotime(date('Y-12-31 23:59:59', strtotime('-2 year')));
                break;
            case 'quarter'://本季度
                $quarter = empty($param) ? ceil((date('n')) / 3) : $param;//获取当前季度
                $timeamp['start'] = mktime(0, 0, 0, (int)$quarter * 3 - 2, 1, (int)date('Y'));
                $timeamp['end'] = mktime(0, 0, 0, (int)$quarter * 3 + 1, 1, (int)date('Y')) - 1;
                break;
            case 'lastQuarter': // 上季度
                $season = ceil((date('n')) / 3) - 1;
                $timeamp['start'] = mktime(0, 0, 0, (int)$season * 3 - 3 + 1, 1, (int)date('Y'));
                $timeamp['end'] = mktime(23, 59, 59, (int)$season * 3, (int)date('t', (int)mktime(0, 0, 0, (int)$season * 3, 1, (int)date("Y"))), (int)date('Y'));
                break;
            case 'lastpreQuarter': // 上上季度
                $season = ceil((date('n')) / 3) - 1;
                $timeamp['start'] = mktime(0, 0, 0, (int)$season * 3 - 6 + 1, 1, (int)date('Y'));
                $timeamp['end'] = mktime(23, 59, 59, (int)$season * 3 - 3, (int)date('t', mktime(0, 0, 0, (int)$season * 3 - 3, 1, (int)date("Y"))), (int)date('Y'));
                break;
            default:
                $timeamp['start'] = strtotime(date('Y-m-d'));
                $timeamp['end'] = strtotime(date('Y-m-d'));
        }
        return $timeamp;
    }
}
